home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Tool Chest / Development Kits / MPW etc. / Debuggers / SADE / SADE 1.4a3 / SADE Example Scripts / MiscProcs next >
Encoding:
Text File  |  1992-07-10  |  5.6 KB  |  168 lines  |  [TEXT/sade]

  1. ##########################################################################################
  2. #    Symbolic Application Debugging Environment 1.4
  3. #
  4. #    copyright Apple Computer, Inc. 1987-1991
  5. #    All rights reserved.
  6. #
  7. ##########################################################################################
  8.  
  9. # displays the title of each window in the window list.
  10. proc displaywindowlist; 
  11.  
  12. define awindow;            # used to contain the pointer to each window record in turn
  13.  
  14.     awindow := ^WindowRecord(windowlist);    # start at the first window, pointed to from low memory.
  15.     while (awindow <> 0) do    # a NIL terminated list.
  16.         printf ("Window Title = \"%P\"\n",^pString(awindow^.titleHandle^)^);        # write the information out.                                
  17.         awindow := ^WindowRecord(awindow^.nextWindow);        # point at the next in the list.
  18.     end;    
  19.  
  20. end; # displaywindowlist
  21.  
  22.  
  23. ###############################################################################
  24. # a small set of routines to list out all of the FCBs
  25.  
  26. #-------------------------------------------------------------------------------------------
  27. #    FCBLen --     returns the length of the FCB, 20 if we are running MFS (which we won't ever be)
  28. #                or what's in $3F6 if HFS.
  29. #-------------------------------------------------------------------------------------------
  30. func FCBLen    ()
  31.  
  32. define FSFCBLen := ^word($3F6)^                    # fetch value of low-memory global
  33. define MFSFCBLen := 20                            # we know this to be true, for ever and ever
  34.  
  35.     if (FSFCBLen < 0)                             # less than zero means MFS
  36.         return(MFSFCBLen);
  37.     else
  38.         return(FSFCBLen);
  39.     end
  40. end    # func FCBLen
  41.  
  42.  
  43. #-------------------------------------------------------------------------------------------
  44. #    DisplayAnFCB -- displays the entryNumth entry in the FCB table.  Does NOT check to see
  45. #                    if the entry is actually in the table, that's left to the caller
  46. #-------------------------------------------------------------------------------------------
  47. proc DisplayAnFCB(entryNum)
  48.     
  49. define theFCBsAddr,theRefNum
  50. # the following are offsets into the FCB
  51. define fileNumOffset := 0;
  52. define PEOFOffset := 12;
  53. define fileTypeOffset := 50;
  54. define fileNameOffset := 62;
  55.  
  56.     theRefNum := (entryNum * FCBLen()) + 2;     # "+2" accounts for the length word at the
  57.                                                 # start of the FCB block
  58.     theFCBsAddr:= FCBsPtr^+ theRefNum;
  59.     
  60.     printf("$%.4X",theRefNum);                     # print the refnum
  61.     if (theFCBsAddr+fileNumOffset)^ = 0         # the file is unused
  62.         printf("     unused\n");
  63.     else
  64.         printf("     $%.8X",(theFCBsAddr+fileNumOffset)^);    # print the file number
  65.         printf("     $%.8X",(theFCBsAddr+PEOFOffset)^);
  66.         printf("     %#s",(theFCBsAddr+fileTypeOffset)^);
  67.         printf("     %P\n",^pstring(theFCBsAddr+fileNameOffset)^);
  68.     end
  69. END;  # proc DisplayAnFCB
  70.  
  71.  
  72. #-------------------------------------------------------------------------------------------
  73. #    DisplayFCBs -- loops through and lists all FCBs by calling DisplayAnFCB
  74. #-------------------------------------------------------------------------------------------
  75. proc DisplayFCBs
  76.  
  77. # global variable
  78. define global FCBsPtr  := $34E                    # location of pointer to FCBs
  79.  
  80. define i,numFCBs
  81.  
  82.     # print header
  83.     numFCBs:= ^Word(FCBsPtr^)^ / FCBLen();     # we don't really need this variable, but what the hey
  84.     printf("There are %t FCBs starting at $%.8X\n\n",numFCBs,FCBsPtr^);
  85.     printf("RefNum    File#         PEOF          FType    Name\n");
  86.     printf("------    -----         ----          -----    ----\n");
  87.     
  88.     for i:= 0 to numFCBs-1                        # FCB table is zero based
  89.         DisplayAnFCB(i)                          # display this FCB
  90.     end    #for
  91.     undefine FCBsPtr;
  92. end; # proc DisplayFCBs
  93.  
  94.  
  95. ###############################################################################
  96. # this proc creates a listing in the specified output file.
  97. # The listing will have each statement of the specified routine
  98. # followed by a disassembly of the code associated with the statement.
  99. # It isn't very pretty, but it might help you spot code generation bugs.
  100. # Note that the routine to be listed must be in a loaded segment. 
  101.     proc InterList(myRoutine,myOutput)
  102.         open myOutput; redirect myOutput
  103.         define looper := 0, junk
  104.         define currentLine, previousLine, lastLine
  105.         currentLine := eval(concat (myroutine,'.(looper)'), '???')    # start with statement 0
  106.             if (TypeOf(currentLine) = 'PString')
  107.                 printf "cannot find program symbol âˆ‚"%t∂"\n",myroutine
  108.                 redirect pop
  109.                 return
  110.             end
  111.         junk := addrtosource(currentLine)                                        # select the statement
  112.             if (junk != 1)
  113.                 printf "cannot find the source for âˆ‚"%t∂"\n",myRoutine
  114.                 redirect pop
  115.                 return
  116.             end
  117.         selection(targetwindow)                                                            # echo the statement
  118.         disasm currentLine..eval(concat (myroutine,'.(looper+1)'))-1 # add the instructions
  119.         " "
  120.         lastLine := eval(concat (myroutine,'.(1000000)'))        # so we can detect the end
  121.         for looper := 1 to 1000000
  122.             previousLine := eval(concat (myroutine,'.(looper-1)')) # so we can detect duplicates
  123.             leave if ( previousLine = lastLine)                                # all done
  124.             currentLine := eval(concat (myroutine,'.(looper)'))
  125.             if (currentLine != previousLine)                                    # if not a duplicate
  126.                 junk := addrtosource(currentLine)
  127.                 selection(targetWindow)
  128.                 " "
  129.                 disasm currentLine..eval(concat (myroutine,'.(looper+1)'))-1
  130.                 " "
  131.             end
  132.         end
  133.         redirect pop
  134.     end
  135.  
  136.  
  137. # example usage
  138.  
  139. # InterList('routinename','filename')
  140.  
  141.  
  142. ###############################################################################
  143. # for the numerically minded--how many debuggers can do factorial?
  144.  
  145. func fact(n)
  146.     if n <= 1.0 then
  147.         return 1.0
  148.     else
  149.         return n * fact(n-1)
  150.     end
  151. end
  152.  
  153.  
  154. proc factorial (n,file)
  155.     define i
  156.     if nargs>1 then
  157.         redirect file
  158.     end
  159.     for i := 1 to n do
  160.         printf("fact(%.2d) = %19.19g\n",i,fact(i))
  161.     end
  162.     if nargs>1 then
  163.         redirect
  164.     end
  165. end
  166.  
  167.  
  168.